{
 "cells": [
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-26T02:32:10.447642Z",
     "start_time": "2025-06-26T02:32:10.431310Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 自定义层\n",
    "import torch\n",
    "import torch.nn.functional as F\n",
    "from torch import nn"
   ],
   "id": "d0ba3b1d98cb25e0",
   "outputs": [],
   "execution_count": 8
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-26T02:32:10.493680Z",
     "start_time": "2025-06-26T02:32:10.479431Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 不带参数的层\n",
    "class CenteredLayer(nn.Module):\n",
    "\tdef __init__(self):\n",
    "\t\tsuper(CenteredLayer, self).__init__()\n",
    "\n",
    "\tdef forward(self, X):\n",
    "\t\treturn X - X.mean()"
   ],
   "id": "e1d5d96908944ffd",
   "outputs": [],
   "execution_count": 9
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-26T02:32:10.525501Z",
     "start_time": "2025-06-26T02:32:10.509307Z"
    }
   },
   "cell_type": "code",
   "source": [
    "layer = CenteredLayer()\n",
    "layer(torch.FloatTensor([1, 2, 3, 4, 5]))"
   ],
   "id": "865aebb26db04ccb",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([-2., -1.,  0.,  1.,  2.])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 10
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-26T02:32:10.555858Z",
     "start_time": "2025-06-26T02:32:10.542169Z"
    }
   },
   "cell_type": "code",
   "source": "net = nn.Sequential(nn.Linear(8, 128),CenteredLayer())",
   "id": "3592be60590e8947",
   "outputs": [],
   "execution_count": 11
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-26T02:32:10.586931Z",
     "start_time": "2025-06-26T02:32:10.572852Z"
    }
   },
   "cell_type": "code",
   "source": [
    "Y = net(torch.randn(4, 8))\n",
    "Y.mean()"
   ],
   "id": "1aecf785a0e98eaa",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor(-1.2107e-08, grad_fn=<MeanBackward0>)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 12
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-26T02:34:17.346699Z",
     "start_time": "2025-06-26T02:34:17.334952Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 带参数的层\n",
    "class MyLinear(nn.Module):\n",
    "\tdef __init__(self,in_units,units):\n",
    "\t\tsuper(MyLinear, self).__init__()\n",
    "\t\tself.weight = nn.Parameter(torch.randn(in_units,units))\n",
    "\t\tself.bias = nn.Parameter(torch.randn(units,))\n",
    "\n",
    "\tdef forward(self, X):\n",
    "\t\tlinear = torch.matmul(X,self.weight.data) + self.bias.data\n",
    "\t\treturn F.relu(linear)"
   ],
   "id": "9d8649e42dc2f47d",
   "outputs": [],
   "execution_count": 14
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-26T02:34:32.768478Z",
     "start_time": "2025-06-26T02:34:32.754464Z"
    }
   },
   "cell_type": "code",
   "source": [
    "linear = MyLinear(5,3)\n",
    "linear.weight"
   ],
   "id": "a04abdf258c9ebe4",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Parameter containing:\n",
       "tensor([[-0.5867,  0.7367,  0.9082],\n",
       "        [-1.0035,  0.2866,  1.4255],\n",
       "        [-0.1185, -1.4708, -0.6140],\n",
       "        [-0.5532, -0.7250,  0.8486],\n",
       "        [ 0.6104, -0.9188, -1.7197]], requires_grad=True)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 15
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-26T02:35:37.442004Z",
     "start_time": "2025-06-26T02:35:37.434019Z"
    }
   },
   "cell_type": "code",
   "source": "linear(torch.randn(2,5))",
   "id": "ee543895a6fbd647",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0.0000, 0.5455, 0.1326],\n",
       "        [0.0000, 0.9308, 1.9948]])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 17
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-26T02:36:21.480082Z",
     "start_time": "2025-06-26T02:36:21.468197Z"
    }
   },
   "cell_type": "code",
   "source": [
    "net = nn.Sequential(MyLinear(68,4),MyLinear(4,1))\n",
    "net(torch.randn(4,68))"
   ],
   "id": "4cd8aeeff213a387",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0.],\n",
       "        [0.],\n",
       "        [0.],\n",
       "        [0.]])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 18
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": "",
   "id": "6278dca22c76cf20"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.22"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
